# coding: utf-8

# -------------------------------------------------------------------------------
# Name:         parser.py
# Description:
# Author:       XiangjunZhao
# EMAIL:        2419352654@qq.com
# Date:         2019/11/18 17:32
# -------------------------------------------------------------------------------
import json
import logging
import re
import jsonpath

from apps.HttpAutoTestService.core.builtin.functions import *
from apps.HttpAutoTestService.core.extractor import Extractor

logger = logging.getLogger(__name__)

# 变量正则表达式，示例：{{var}},{{var[1]}},{{var[1:5:2]}}
variable_regex_compile = re.compile(r"\{\{(\w+)(\[([-:\d]+)\])?\}\}")
# 方法正则表达式，示例：$func1({{var_1}}, {{var_3}})$
function_regex_compile = re.compile(r"\$(\w+\(.*?\))\$")


def regex_replace_variables(content, variables_mapping):
    """
    查询content中符合variable_regex_compile正则表达式的变量字符串，
    再从variables_mapping中提取相应变量值，
    再将变量值替换掉content中的变量字符串
    Args:
        content:
        variables_mapping:

    Returns:

    """
    content = content if isinstance(content, str) else json.dumps(content, ensure_ascii=False)
    while variable_regex_compile.search(content):
        replaced_key = temp_replaced_key = variable_regex_compile.search(content).group(0)
        logger.info(f'正在解析变量：{temp_replaced_key}')
        variable_key = variable_regex_compile.search(content).group(1)
        slice_key = variable_regex_compile.search(content).group(3)
        replaced_value = jsonpath.jsonpath(variables_mapping, variable_key) or None
        if isinstance(replaced_value, list):
            if len(replaced_value) == 1:
                replaced_value = replaced_value[0]
        if slice_key:
            # 执行列表切片功能
            slice_value = slice_key.split(':')
            slice_list = []
            slice_kwargs = {}
            for item in slice_value:
                if item:
                    slice_list.append(int(item))
                else:
                    slice_list.append(None)
            if len(slice_list) == 1:
                # 取指定下标的值
                index = slice_list[0]
                slice_kwargs = {'index': index}
            elif len(slice_list) > 1:
                # 取指定下标范围内的值
                key = ['start', 'end', 'step']
                slice_kwargs = dict(zip(key, slice_list))
                if hasattr(slice_kwargs, 'step'):
                    slice_kwargs['step'] = slice_kwargs['step'] or 1
            replaced_value = slice(replaced_value, **slice_kwargs)

        if not isinstance(replaced_value, str):
            if content.find(f'"{replaced_key}"') != -1:
                replaced_key = f'"{replaced_key}"'
            replaced_value = json.dumps(replaced_value, ensure_ascii=False)
        logger.info(f'变量 {temp_replaced_key} 的解析结果为：{replaced_value}')
        content = content.replace(replaced_key, replaced_value)
    return content


def regex_replace_functions(content, ext_method_online_module, ext_methods_online):
    """
    查询content中符合function_regex_compile正则表达式的方法字符串，
    再使用eval方法得到方法字符串的返回值，
    再将方法返回值替换掉content中的方法字符串
    Args:
        content:
        ext_method_online_module: ext_method_online.py模块
        ext_methods_online: ext_method_online.py模块中的方法

    Returns:

    """
    content = content if isinstance(content, str) else json.dumps(content, ensure_ascii=False)
    while function_regex_compile.search(content):
        replaced_key = temp_replaced_key = function_regex_compile.search(content).group(0)
        logger.info(f'正在解析方法：{temp_replaced_key}')
        fun = function_regex_compile.search(content).group(1)
        if ext_method_online_module and fun.split('(')[0] in ext_methods_online:
            # 执行在线扩展方法(优先级高于 扩展函数和系统内置函数)
            replaced_value = eval(f'ext_method_online_module.{fun}')
        else:
            replaced_value = eval(fun)

        if not isinstance(replaced_value, str):
            if content.find(f'"{replaced_key}"') != -1:
                replaced_key = f'"{replaced_key}"'
            replaced_value = json.dumps(replaced_value, ensure_ascii=False)
        logger.info(f'方法 {temp_replaced_key} 的运行结果为：{replaced_value}')
        content = content.replace(replaced_key, replaced_value)
    return content


if __name__ == '__main__':
    variables_mapping1 = {
        "name": "leon",
        "age": 18,
        "ages": [18, 19, 20],
        "hobby": ["book", "bike"],
        "var": [1, 2, 3, 4, 5, 6, 7, 8, 9],
        'name1': [
            {'id': [1]},
            {'id': [2]},
            {'id': [3]}
        ]
    }
    output_mapping = {
        "var": "$.var[1:]",
        "ids": "$..id"
    }
    extractor = Extractor()
    extractor.uniform_output(output_mapping)
    result = extractor.extract_output(variables_mapping1)
    print(result)

    user1 = {
        "var": "{{var}}"
    }
    content = regex_replace_variables(user1, result)
    print(content)
